#pragma once

class CSpreadsheet;
class CDisturbance;
class CPhiGamma
{
public:
    CPhiGamma();
    ~CPhiGamma();
    // load data from spreadsheet to here
    virtual void load(const vector<CSpreadsheet*> &vSpreadsheet_,const string& strFileName_ );
    // save changes into spreadsheets
    virtual void precompute();
    virtual void precomputeEachTrial();

    virtual void SaveToFile();
    virtual void clear();
    //Helpers
    void UpdateOutput(int nCurrFrameIdx_,double dCurrControlState_);
    int frameRate();
public:
    const   CMatrix<double>&    GetControlValues()          const   {return _mControlValues;}
            CMatrix<double>&    SetControlValues()                 {return _mControlValues;}
    const   CMatrix<double>&    GetStateValues()        const    {return _mStateValues;}
            CMatrix<double>&    SetStateValues()                {return _mStateValues;}
    const   CMatrix<double>&    GetOutputValues()        const    {return _mOutputValues;}
            CMatrix<double>&    SetOutputValues()                {return _mOutputValues;}

    //const   vector<double>&        GetDistGains()            const    {return _vDistGains;}
    //        vector<double>&        SetDistGains()                    {return _vDistGains;}
    const   vector<string>&        spectraFileNames()        const    {return _vsSpectraFileNames;}
            vector<string>&        setSpectraFileNames()              {return _vsSpectraFileNames;}
    const   double&        GetControlGain()        const    {return _nControlGain;}
            double&        SetControlGain()                {return _nControlGain;}
    // Phi Gama
    const int&        GetNumStates()          const    {return _nStates;}
          int&        SetNumStates()                   {return _nStates;}
    const int&        GetNumOutputs()         const    {return _nOutputs;}
          int&        SetNumOutputs()                  {return _nOutputs;}
    const int&        GetNumControls()        const    {return _nControls;}
          int&        SetNumControls()                 {return _nControls;}
    const int&        controlsOrder()        const    {return _nOrderControl;}
          int&        setControlOrder()                 {return _nOrderControl;}
    const int&        numDisturbances()        const    {return _nNumDisturbances;}
          int&        setNumDisturbances()              {return _nNumDisturbances;}

        // phi gamma file
    const CMatrix<double>& phi() const {return _mPhi;}
          CMatrix<double>& setPhi()    {return _mPhi;}
    const CMatrix<double>& gamma() const {return _mGamma;}
          CMatrix<double>& setGamma()    {return _mGamma;}
    const CMatrix<double>& cee() const {return _mCee;}
          CMatrix<double>& setCee()    {return _mCee;}
    const CMatrix<double>& dee() const {return _mDee;}
          CMatrix<double>& setDee()    {return _mDee;}
    CDisturbance* const disturbance(int nIdx_) const 
    {
        if(nIdx_<(int)_vpDisturbances.size())
            return _vpDisturbances[nIdx_];
        else
            return 0;
    }
protected:
    vector<CDisturbance*> _vpDisturbances;

    // experiment (run) data
    CMatrix<double> _mControlValues;
    CMatrix<double> _mOutputValues;
    CMatrix<double> _mStateValues;

    // from input files
    double _nControlGain; // from matrix file
    //vector<double> _vDistGains; // from spectra file
    vector<string> _vsSpectraFileNames; // from spectra file

    //Sizes of Dimensions
    int _nStates;
    int _nOutputs;
    int _nControls;
    int _nOrderControl;
    int _nNumDisturbances;

    // Phi gamma file
    CMatrix<double> _mPhi; 
    CMatrix<double> _mGamma;
    CMatrix<double> _mCee;
    CMatrix<double> _mDee;
};
